package com.huatai.bi.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huatai.bi.config.ExecutorConfig;
import com.huatai.bi.config.LocalFileConfig;
import com.huatai.bi.constant.RedisConstant;
import com.huatai.bi.constant.ScreenConstant;
import com.huatai.bi.dto.BigScreenPageDTO;
import com.huatai.bi.dto.bigScreen.SaveAsVersionScreenDTO;
import com.huatai.bi.dto.bigScreen.ScreenAuthDTO;
import com.huatai.bi.entity.*;
import com.huatai.bi.mapper.BigScreenPageMapper;
import com.huatai.bi.query.ScreenQuery;
import com.huatai.bi.service.*;
import com.huatai.bi.utils.CodeGenerateUtils;
import com.huatai.bi.utils.ImageUtil;
import com.huatai.bi.vo.bigScreenVO.*;
import com.huatai.common.config.MinioAPI;
import com.huatai.common.error.exception.ServiceException;
import com.huatai.common.util.AuthUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
* @author hecai
* @description 针对表【big_screen_page(态势模板)】的数据库操作Service实现
* @createDate 2024-06-20 14:11:51
*/
@Service
@Slf4j
public class BigScreenPageServiceImpl extends ServiceImpl<BigScreenPageMapper, BigScreenPageEntity> implements BigScreenPageService{
    @Autowired
    private BigScreenPageVersionService bigScreenPageVersionService;
    @Autowired
    LocalFileConfig localFileConfig;
    @Autowired
    private BigScreenTypeService bigScreenTypeService;
    @Autowired
    @Lazy
    private ExecutorConfig executorConfig;
    @Autowired
    private MinioAPI minioAPI;
    @Autowired
    private BigScreenDataSetService bigScreenDataSetService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    SysDictDataService sysDictDataService;

    /**
     * 根据code切换历史版本
     * @param code
     * @return
     */
    @Override
    public BigScreenPageVersionVO getScreenByCode(String code){
        BigScreenPageVersionEntity screenVersionByCode = bigScreenPageVersionService.getScreenVersionByCode(code);
        if(null != screenVersionByCode){
            bigDesignLock(screenVersionByCode.getParentCode(),false);
        }
        BigScreenPageVersionVO screenInfoByCode = this.getScreenInfoByCode(screenVersionByCode, code);
        return screenInfoByCode;
    }

    /**
     * 去除限定
     * @param code
     * @return
     */
    public Boolean removeLimit(String parentCode){
        return stringRedisTemplate.delete(RedisConstant.SCREEN_KEY + parentCode);
    }

    /**
     * 加锁
     * @param code
     * @return
     */
    public void bigDesignLock(String code,Boolean exceptionFlag){
        String key = RedisConstant.SCREEN_KEY + code;
        if(stringRedisTemplate.hasKey(key)){
            String userName = stringRedisTemplate.opsForValue().get(key);
            if(userName.equals(AuthUtil.getUser().getName())){
                stringRedisTemplate.expire(key,5,TimeUnit.MINUTES);
            }else if(exceptionFlag){
                throw new ServiceException(String.format("态势正在被 %s 编辑",userName));
            }
        }else{
            stringRedisTemplate.opsForValue().set(key,AuthUtil.getUser().getName(),5,TimeUnit.MINUTES);
        }
    }

    /**
     * 判断当前用户是否是正在设计大屏的用户
     * @param code
     * @return
     */
    public Boolean vailBigDesignUser(String code){
        String key = RedisConstant.SCREEN_KEY + code;
        if(stringRedisTemplate.hasKey(key)){
            String userName = stringRedisTemplate.opsForValue().get(key);
            if(userName.equals(AuthUtil.getUser().getName())){
                return true;
            }
        }
        return false;
    }

    /**
     * 大屏页组件详情
     * @param dto
     * @return
     */
    @Override
    public BigScreenPageVersionVO getScreenByParentCode(SaveAsVersionScreenDTO dto){
        String code = dto.getCode();
        if(ObjectUtil.isEmpty(code)){
            throw new ServiceException("请选择态势");
        }
//        //编辑中禁止其他人修改
//        String key = RedisConstant.SCREEN_KEY + code;
//        String username = SecurityUtils.getUsername();
//        if(stringRedisTemplate.hasKey(key)){
//            String userNameRedis = stringRedisTemplate.opsForValue().get(key);
//            //被锁定  自己可编辑
//            if(ObjectUtil.isNotEmpty(username) && !username.equalsIgnoreCase(userNameRedis)){
//                throw new ServiceException("该大屏正在被"+username+"编辑中，请稍后重试");
//            }
//        }
//        //缓存一天 刷新缓存
//        stringRedisTemplate.opsForValue().set(key, username, 24, TimeUnit.HOURS);
        if(!dto.isPreviewFlag()){
            bigDesignLock(dto.getCode(),false);
        }
        BigScreenPageVersionEntity screenVersionByCode = bigScreenPageVersionService.getScreenVersionByParentCode(code);
        BigScreenPageVersionVO screenInfoByCode = this.getScreenInfoByCode(screenVersionByCode, code);
        return screenInfoByCode;
    }

    /**
     * 组建大屏详情
     * @param screenVersionByCode
     * @param code
     * @return
     */
    private BigScreenPageVersionVO getScreenInfoByCode(BigScreenPageVersionEntity screenVersionByCode,String code){
        BigScreenPageVersionVO bigScreenPageVersionVO = BeanUtil.copyProperties(screenVersionByCode, BigScreenPageVersionVO.class);
        bigScreenPageVersionVO.setVersionName(screenVersionByCode.getName());
        BigScreenPageDTO bigScreenPageDTO = JSON.parseObject(screenVersionByCode.getConfig(), BigScreenPageDTO.class);
        bigScreenPageVersionVO.setBigConfig(bigScreenPageDTO);
        bigScreenPageVersionVO.setScreenParentCode(bigScreenPageDTO.getParentCode());
        BigScreenPageEntity infoByCode = this.getInfoByCode(screenVersionByCode.getParentCode());
        if(ObjectUtil.isNotEmpty(infoByCode)){
            bigScreenPageVersionVO.setScreenName(infoByCode.getName());
        }
        return bigScreenPageVersionVO;
    }

    /**
     * 修改大屏组件
     * @param bigScreenPageDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String updateScreen(BigScreenPageDTO bigScreenPageDTO) {
        /*//编辑中禁止其他人修改
        String key = RedisConstant.SCREEN_KEY + bigScreenPageDTO.getParentCode();
        if(stringRedisTemplate.hasKey(key)){
            if(ObjectUtil.isEmpty(SecurityUtils.getUsername())){
                throw new ServiceException("未登录！！！");
            }
            //判断是否是自己在编辑 是自己在编辑则跳过
            if(!stringRedisTemplate.opsForValue().get(key).equals(SecurityUtils.getUsername())){
                throw new ServiceException("该大屏正在被"+stringRedisTemplate.opsForValue().get(key)+"编辑中，请稍后重试");
            }
        }*/

        if(StringUtils.isEmpty(bigScreenPageDTO.getCode())){
            throw new ServiceException("编码不能为空");
        }

        BigScreenPageVersionEntity screenVersionByCode = bigScreenPageVersionService.getScreenVersionByCode(bigScreenPageDTO.getCode());
        if(ObjectUtil.isEmpty(screenVersionByCode)){
            throw new ServiceException("该态势不存在");
        }

        bigDesignLock(bigScreenPageDTO.getCode(),true);

        //更新上级的封面图片 只是更新已经发布的照片
        String base64Str = bigScreenPageDTO.getCoverPicture();
        String fileName = new ImageUtil().saveCoverPictureMinio(base64Str, bigScreenPageDTO.getCode(),minioAPI);
        bigScreenPageDTO.setCoverPicture(fileName);
        if(screenVersionByCode.getIsPublish().equals(ScreenConstant.PUBLISH)){
            //设置封面图片
            if(StringUtils.isNotEmpty(bigScreenPageDTO.getCoverPicture())){
//                String base64Str = bigScreenPageDTO.getCoverPicture();
//                ImageUtil imageUtil = new ImageUtil();
//                String fileName = imageUtil.saveCoverPictureMinio(base64Str, bigScreenPageDTO.getCode(),minioAPI);
                bigScreenPageDTO.setCoverPicture(bigScreenPageDTO.getCoverPicture());
            }
            BigScreenPageEntity infoByCode = this.getInfoByCode(screenVersionByCode.getParentCode());
            if(ObjectUtil.isNotEmpty(infoByCode) && infoByCode.getPublishCode().equalsIgnoreCase(screenVersionByCode.getCode())){
                infoByCode.setCoverPicture(bigScreenPageDTO.getCoverPicture());
                //infoByCode.setName(screenVersionByCode.getName());
                this.updateById(infoByCode);
                log.info("更新上级的封面图片：{}",infoByCode.getCode());
            }
        }
        screenVersionByCode.setCoverPicture(bigScreenPageDTO.getCoverPicture());
        screenVersionByCode.setConfig(JSON.toJSONString(bigScreenPageDTO));
        bigScreenPageVersionService.updateById(screenVersionByCode);
        CompletableFuture.runAsync(()->{
            BigScreenDataSetEntity bigScreenDataSetEntity = new BigScreenDataSetEntity();
            bigScreenDataSetEntity.setId(screenVersionByCode.getId());
            bigScreenDataSetEntity.setCode(screenVersionByCode.getCode());
            bigScreenDataSetEntity.setParentCode(screenVersionByCode.getParentCode());
            List<JSONObject> chartList = bigScreenPageDTO.getChartList();
            if (CollectionUtils.isNotEmpty(chartList)) {
                List<String> idsList = new ArrayList<>();
                for (JSONObject jsonObject : chartList){
                    JSONObject dataSetting = jsonObject.getJSONObject("dataSetting");
                    if(ObjectUtil.isNotEmpty(dataSetting)){
                        JSONObject aggregation = dataSetting.getJSONObject("aggregation");
                        if(ObjectUtil.isNotEmpty(aggregation)){
                            String id = aggregation.getString("id");
                            if(StringUtils.isNotEmpty(id)){
                                idsList.add(id);
                            }
                        }
                    }
                }
                if(idsList!=null && idsList.size()>0){
                    idsList = idsList.stream().distinct().collect(Collectors.toList());
                    String ids = StringUtils.join(idsList, ",");
                    bigScreenDataSetEntity.setDtIds(ids);
                    bigScreenDataSetService.saveOrUpdate(bigScreenDataSetEntity);
                }
            }

        }, Executors.newSingleThreadExecutor());
        return bigScreenPageDTO.getCode();
    }

	/**
	 * 新增大屏
	 * @param bigScreenPageDTO
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public List<BigScreenPageEntity> copyScreen(BigScreenPageDTO bigScreenPageDTO) {
		if(CollectionUtils.isEmpty(bigScreenPageDTO.getCopyCodeList())){
			return null;
		}
		List<BigScreenPageEntity> screenList = this.baseMapper.selectList(
			new LambdaQueryWrapper<BigScreenPageEntity>()
				.in(BigScreenPageEntity::getCode,bigScreenPageDTO.getCopyCodeList())
		);

		for (BigScreenPageEntity bigScreenPageEntity : screenList) {
			bigScreenPageEntity.setId(null);

			//历史版本
			LambdaQueryWrapper<BigScreenPageVersionEntity> qw = new LambdaQueryWrapper<>();
			qw.eq(BigScreenPageVersionEntity::getParentCode, bigScreenPageEntity.getCode());
			qw.orderByDesc(BigScreenPageVersionEntity::getUpdateTime);
			List<BigScreenPageVersionEntity> list = bigScreenPageVersionService.list(qw);
			if(CollectionUtil.isEmpty(list)){
				throw new ServiceException("未找到态势信息");
			}
			BigScreenPageVersionEntity versionEntity = list.stream().filter(p -> p.getIsPublish().equals(ScreenConstant.PUBLISH)).findFirst().orElse(null);
			if(versionEntity == null){
				versionEntity = list.get(0);
			}

			bigScreenPageEntity.setCode(CodeGenerateUtils.generate("screen"));
			bigScreenPageEntity.setConfig(JSON.toJSONString(JSONObject.parseObject(bigScreenPageEntity.getConfig())));

			versionEntity.setId(null);
			versionEntity.setParentCode(bigScreenPageEntity.getCode());
			versionEntity.setCode(CodeGenerateUtils.generate("screen"));
			this.saveOrUpdate(bigScreenPageEntity);
			bigScreenPageVersionService.saveOrUpdate(versionEntity);
		}
		return screenList;
	}

    /**
     * 新增大屏
     * @param bigScreenPageDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addScreen(BigScreenPageDTO bigScreenPageDTO) {
        /*String parentCode = bigScreenPageDTO.getParentCode();
        if(StringUtils.isEmpty(parentCode)){
            throw new ServiceException("请选择分组！！");
        }*/

        //判断大屏名称是否重命
        /*long count = this.count(Wrappers.<BigScreenPageEntity>lambdaQuery(BigScreenPageEntity.class)
                .eq(BigScreenPageEntity::getParentCode, parentCode)
                .eq(BigScreenPageEntity::getName, bigScreenPageDTO.getName()));
        if(count>0){
            throw new ServiceException("名称重复，请修改");
        }*/
        bigScreenPageDTO.setIsPublish(ScreenConstant.NOTPUBLISH);
        String code = CodeGenerateUtils.generate("screen");
        bigScreenPageDTO.setCode(code);
        List<JSONObject> chartList = bigScreenPageDTO.getChartList();
        if(CollectionUtil.isEmpty(chartList)){
            chartList= new ArrayList<>();
        }
        //设置历史版本
        BigScreenPageVersionEntity versionEntity = new BigScreenPageVersionEntity();
        //上级
        versionEntity.setParentCode(bigScreenPageDTO.getCode());
        versionEntity.setName(bigScreenPageDTO.getName());
        versionEntity.setIsPublish(bigScreenPageDTO.getIsPublish());
        versionEntity.setCode(CodeGenerateUtils.generate("screen"));
        versionEntity.setConfig(JSON.toJSONString(bigScreenPageDTO.getConfig()));
        //设置封面图片
        if(StringUtils.isNotEmpty(bigScreenPageDTO.getCoverPicture())){
            String base64Str = bigScreenPageDTO.getCoverPicture();
            ImageUtil imageUtil = new ImageUtil();
            String fileName = imageUtil.saveCoverPictureMinio(base64Str, bigScreenPageDTO.getCode(),minioAPI);
            bigScreenPageDTO.setCoverPicture(fileName);
            versionEntity.setCoverPicture(fileName);
        }
        BigScreenPageEntity bigScreenPageEntity = BeanUtil.copyProperties(bigScreenPageDTO, BigScreenPageEntity.class);
        versionEntity.setConfig(JSON.toJSONString(bigScreenPageDTO));
        bigScreenPageEntity.setConfig(JSON.toJSONString(bigScreenPageDTO.getConfig()));
        this.saveOrUpdate(bigScreenPageEntity);
        bigScreenPageVersionService.saveOrUpdate(versionEntity);
        return code;
    }

    /**
     * 另存为一个版本
     * @param code         当前版本唯一标识
     * @param versionName  新版本名称
     * @return
     */
    public Boolean saveAsVersion(String code,String versionName){
        BigScreenPageVersionEntity screenVersionByCode = bigScreenPageVersionService.getScreenVersionByCode(code);
        if (ObjectUtil.isEmpty(screenVersionByCode)){
            throw new ServiceException("该版本不存在");
        }

        //判断版本名称是否重复
        long count = bigScreenPageVersionService.count(Wrappers.<BigScreenPageVersionEntity>lambdaQuery(BigScreenPageVersionEntity.class)
                .eq(BigScreenPageVersionEntity::getParentCode, screenVersionByCode.getParentCode())
                .eq(BigScreenPageVersionEntity::getName, versionName));
        if(count>0){
            throw new ServiceException("名称重复，请修改");
        }
        bigDesignLock(screenVersionByCode.getParentCode(),false);
        screenVersionByCode.setId(IdWorker.getId());
        screenVersionByCode.setCode(CodeGenerateUtils.generate("screen"));
        screenVersionByCode.setName(versionName);
        screenVersionByCode.setIsPublish(ScreenConstant.NOTPUBLISH);

		//清空配置
		BigScreenPageDTO config = JSON.parseObject(screenVersionByCode.getConfig(),BigScreenPageDTO.class);
		config.setChartList(new ArrayList<>());
		screenVersionByCode.setConfig(JSON.toJSONString(config));

        return bigScreenPageVersionService.save(screenVersionByCode);
    }

	/**
	 * 修改版本名称
	 * @param code         当前版本唯一标识
	 * @param versionName  新版本名称
	 * @return
	 */
	public Boolean updateVersionName(String code,String versionName){
		BigScreenPageVersionEntity screenVersionByCode = bigScreenPageVersionService.getScreenVersionByCode(code);
		if (ObjectUtil.isEmpty(screenVersionByCode)){
			throw new ServiceException("该主题不存在");
		}

		//判断版本名称是否重复
		long count = bigScreenPageVersionService.count(Wrappers.<BigScreenPageVersionEntity>lambdaQuery(BigScreenPageVersionEntity.class)
			.eq(BigScreenPageVersionEntity::getParentCode, screenVersionByCode.getParentCode())
			.eq(BigScreenPageVersionEntity::getName, versionName)
			.ne(BigScreenPageVersionEntity::getCode,code));
		if(count>0){
			throw new ServiceException("名称重复，请修改");
		}
		screenVersionByCode.setName(versionName);
		return bigScreenPageVersionService.save(screenVersionByCode);
	}


	/**
     * 态势另存为
     * @param parentCode
     * @param screenParentCode
     * @param screenName
     * @return
     */
    @Override
    public Boolean saveAsScreen(String parentCode,String screenParentCode,String screenName){
        BigScreenPageEntity bigScreenPageEntity = this.getInfoByCode(parentCode);
        if(ObjectUtil.isEmpty(bigScreenPageEntity)){
            throw new ServiceException("该大屏不存在");
        }
        BigScreenTypeEntity bigScreenTypeEntity = bigScreenTypeService.getInfoByCode(screenParentCode);
        if(ObjectUtil.isEmpty(bigScreenTypeEntity)){
            throw new ServiceException("该目录不存在");
        }
        bigDesignLock(parentCode,false);


        //判断版本名称是否重复
        long count = this.count(Wrappers.<BigScreenPageEntity>lambdaQuery(BigScreenPageEntity.class)
                .eq(BigScreenPageEntity::getParentCode, screenParentCode)
                .eq(BigScreenPageEntity::getName, screenName));
        if(count>0){
            throw new ServiceException("名称重复，请修改");
        }

        bigScreenPageEntity.setName(screenName);
        bigScreenPageEntity.setParentCode(screenParentCode);
        return this.updateById(bigScreenPageEntity);
    }

    /**
     * 获取历史版本
     * @param parentCode 上级
     * @param code       当前
     * @return
     */
    @Override
    public List<ScreenVersionVO> getHistoryVerison(String parentCode,String code){
        List<ScreenVersionVO> list =new ArrayList<>();
        List<BigScreenPageVersionEntity> historyVerison = bigScreenPageVersionService.getHistoryVerison(parentCode);
        for (BigScreenPageVersionEntity entity : historyVerison){
            ScreenVersionVO vo =new ScreenVersionVO();
            vo.setCode(entity.getCode());
            vo.setName(entity.getName());
            vo.setIsSelect(false);
            if(code.equalsIgnoreCase(entity.getCode())){
                vo.setIsSelect(true);
            }
            vo.setCreateTime(entity.getCreateTime()==null?null:entity.getCreateTime());
            vo.setCreateBy(entity.getCreateBy());
			vo.setConfig(JSON.parseObject(entity.getConfig(),BigScreenPageDTO.class));
            list.add(vo);
        }
        return list;
    }

    /**
     * 获取分页数据
     * @param query
     * @return
     */
    public Page<BigScreenPageEntity> getPage(ScreenQuery query) {
        Page<BigScreenPageEntity> page = new Page<>(query.getPageIndex(), query.getPageSize());
        LambdaQueryWrapper<BigScreenPageEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotEmpty(query.getParentCode()),BigScreenPageEntity::getParentCode, query.getParentCode());
        wrapper.like(StringUtils.isNotEmpty(query.getName()),BigScreenPageEntity::getName, query.getName());
        wrapper.orderByAsc(BigScreenPageEntity::getOrderNum);
        page = this.page(page, wrapper);
        if(ObjectUtil.isNotEmpty(page) && ObjectUtil.isNotEmpty(page.getRecords())){
            page.getRecords().forEach(item->{
                if(StringUtils.isNotEmpty(item.getCoverPicture())){
                    item.setCoverPicture(minioAPI.getCOMINFO()+"/"+item.getCoverPicture());
                }
                if(ObjectUtil.isNotEmpty(item.getConfig())){
                    item.setConfigObj(JSON.parseObject(item.getConfig()));
                }
            });
        }
        return page;
    }

    public Boolean updateScreenConfig(BigScreenPageEntity entity){
        if(StringUtils.isEmpty(entity.getParentCode())){
            throw new ServiceException("目录不能为空");
        }
        String code = entity.getCode();
        BigScreenPageEntity screenByCode = this.getInfoByCode(code);
        if(ObjectUtil.isEmpty(screenByCode)){
            throw new ServiceException("该大屏不存在");
        }

        //判断大屏名称是否重复
        long count = this.count(Wrappers.<BigScreenPageEntity>lambdaQuery(BigScreenPageEntity.class)
                .eq(BigScreenPageEntity::getParentCode, entity.getParentCode())
                .eq(BigScreenPageEntity::getName, entity.getName())
                .ne(BigScreenPageEntity::getCode, code));
        if(count>0){
            throw new ServiceException("名称重复，请修改");
        }

        screenByCode.setName(entity.getName());
        screenByCode.setConfig(JSON.toJSONString(entity.getConfigObj()));
        screenByCode.setOrderNum(entity.getOrderNum());
        screenByCode.setParentCode(entity.getParentCode());
        screenByCode.setType(entity.getType());
        return this.updateById(screenByCode);
    }

    /**
     * 根据编码获取详情
     * @param code
     * @return
     */
    public BigScreenPageEntity getInfoByCode(String code){
        return this.getOne(new LambdaQueryWrapper<BigScreenPageEntity>().eq(BigScreenPageEntity::getCode, code));
    }

    /**
     * 移除态势模板
     * @param code
     * @return
     */
    public Boolean removeByCode(String code){
        return this.remove(new LambdaQueryWrapper<BigScreenPageEntity>().eq(BigScreenPageEntity::getCode, code));
    }

    /**
     * 授权场景席位
     * @param parentCode  态势模板
     * @param ids  席位id
     * @return
     */
    public Boolean authScreenBycode(String parentCode,List<String> ids){
        if(CollectionUtil.isEmpty(ids)){
            throw new ServiceException("请选择席位！！！");
        }
        BigScreenPageEntity entity = this.getInfoByCode(parentCode);
        if(ObjectUtil.isEmpty(entity)){
            throw new ServiceException("该态势模板不存在！！！");
        }
        entity.setSeatId(StringUtils.join(ids, ","));
        return this.updateById(entity);
    }

    /**
     * 态势发布
     * @param code
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean publishScreen(String code,List<String> dirs,Integer publishOrder){
        BigScreenPageVersionEntity screenVersionByCode = bigScreenPageVersionService.getScreenVersionByCode(code);
        if(ObjectUtil.isEmpty(screenVersionByCode)){
            throw new ServiceException("该态势模板不存在！！！");
        }
        if(screenVersionByCode.getIsPublish().equals(ScreenConstant.PUBLISH)){
            throw new ServiceException("该态势模板已发布！！！");
        }
        String parentCode = screenVersionByCode.getParentCode();
        BigScreenPageEntity infoByCode = this.getInfoByCode(parentCode);
        if(ObjectUtil.isEmpty(infoByCode)){
            throw new ServiceException("该态势不存在！！！");
        }
        List<BigScreenPageVersionEntity> list = bigScreenPageVersionService.list(Wrappers.<BigScreenPageVersionEntity>lambdaQuery()
                .eq(BigScreenPageVersionEntity::getParentCode, parentCode));
        //历史版本也只能有一个能被发布
        for (BigScreenPageVersionEntity item : list){
            //默认设置不发布
            item.setIsPublish(ScreenConstant.NOTPUBLISH);
            //发布当前版本
            if(item.getCode().equals(code)){
                item.setIsPublish(ScreenConstant.PUBLISH);
            }
        }
        if(list.stream().filter(p->p.getIsPublish().equals(ScreenConstant.PUBLISH)).count()!=1){
            throw new ServiceException("该态势模板发布失败，请检查！！！");
        }
        bigScreenPageVersionService.updateBatchById(list);
        infoByCode.setPublishDir(StringUtils.join(dirs, ","));
        infoByCode.setPublishOrder(publishOrder);
        infoByCode.setPublishTime(new Date());
        infoByCode.setIsPublish(ScreenConstant.PUBLISH);
        infoByCode.setPublishCode(screenVersionByCode.getCode());
        this.updateById(infoByCode);
        return true;
    }

	/**
	 * 态势取消发布
	 * @param code
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public Boolean cancelPublishScreen(String code){
		BigScreenPageEntity infoByCode = this.getInfoByCode(code);
		if(ObjectUtil.isEmpty(infoByCode)){
			throw new ServiceException("该态势不存在！！！");
		}
		if(infoByCode.getIsPublish().equals(ScreenConstant.NOTPUBLISH)){
			throw new ServiceException("该态势模板未发布！！！");
		}
		bigScreenPageVersionService.update(Wrappers.lambdaUpdate(BigScreenPageVersionEntity.class).eq(
			BigScreenPageVersionEntity::getParentCode,code
		).set(BigScreenPageVersionEntity::getIsPublish,ScreenConstant.NOTPUBLISH));
		infoByCode.setPublishDir(null);
		infoByCode.setPublishOrder(0);
		infoByCode.setPublishTime(new Date());
		infoByCode.setIsPublish(ScreenConstant.NOTPUBLISH);
		infoByCode.setPublishCode(null);
		this.updateById(infoByCode);
		return true;
	}

    /**
     * 根据目录编码获取对应目录编码下的大屏清单
     * @param screenParentCode
     */
    public List<BigScreenDownList> getDownList(String screenParentCode){
        List<BigScreenPageEntity> list = this.list(Wrappers.<BigScreenPageEntity>lambdaQuery()
                .eq(BigScreenPageEntity::getParentCode, screenParentCode));
        return list.stream().map(item->{
            BigScreenDownList bigScreenDownList = new BigScreenDownList();
            bigScreenDownList.setCode(item.getCode());
            bigScreenDownList.setName(item.getName());
            return bigScreenDownList;
        }).collect(Collectors.toList());
    }

    /**
     * 根据目录编码获取对应目录编码下的大屏清单
     * @param screenParentCode
     */
    @Override
    public List<DownTreeListVO> getDownListTree(String screenParentCode){
        List<DownTreeListVO> dataList = new ArrayList<>();
        List<BigScreenTypeEntity> list = this.bigScreenTypeService.list(Wrappers.<BigScreenTypeEntity>lambdaQuery(BigScreenTypeEntity.class).orderByAsc(BigScreenTypeEntity::getOrderNum)
                .orderByDesc(BigScreenTypeEntity::getCreateTime));
        List<BigScreenPageEntity> bigScreenPageEntityList = this.list(Wrappers.<BigScreenPageEntity>lambdaQuery(BigScreenPageEntity.class)
                .select(BigScreenPageEntity::getId, BigScreenPageEntity::getParentCode, BigScreenPageEntity::getName, BigScreenPageEntity::getCode));
        //查询对应节点下的树结构
        if(StringUtils.isNotEmpty(screenParentCode)){
            BigScreenTypeEntity infoByCode = this.bigScreenTypeService.getInfoByCode(screenParentCode);
            List<DownTreeListVO> treeList = getTreeList(infoByCode.getId(), list,bigScreenPageEntityList);
            treeList.addAll(rootTreeList(infoByCode, bigScreenPageEntityList));
            DownTreeListVO root = new DownTreeListVO();
            root.setTypeName(infoByCode.getName());
            root.setPid(infoByCode.getPid());
            root.setId(infoByCode.getId());
            root.setChildren(treeList);
            root.setIsDirct(true);
            root.setCode(infoByCode.getCode());
            dataList.add(root);
        }else {//查询全部
            dataList = getTreeList(0L, list,bigScreenPageEntityList);
        }

        return dataList;
    }

    /**
     * 遍历树 组装数据
     * @param treeList
     * @param pageList
     */
    private List<DownTreeListVO> getTreeInfoList(List<DownTreeListVO> treeList,List<BigScreenPageEntity> pageList){
        for (DownTreeListVO tree : treeList){
            if(tree.getChildren()!=null && tree.getChildren().size()>0){
                getTreeInfoList(tree.getChildren(), pageList);
            }
            List<BigScreenPageEntity> collect = pageList.stream().filter(p -> p.getParentCode().equalsIgnoreCase(tree.getCode())).collect(Collectors.toList());
            if(collect!=null && collect.size()>0){
                for (BigScreenPageEntity item : collect){
                    DownTreeListVO downTreeListVO = new DownTreeListVO();
                    downTreeListVO.setBigScreenId(item.getId());
                    downTreeListVO.setBigScreenName(item.getName());
                    downTreeListVO.setCode(item.getCode());
                    downTreeListVO.setId(tree.getId());
                    downTreeListVO.setIsDirct(false);
                    downTreeListVO.setPid(tree.getPid());
                    downTreeListVO.setTypeName(tree.getTypeName());
                    downTreeListVO.setChildren(new ArrayList<>());
                    treeList.add(downTreeListVO);
                }
            }
        }
        return treeList;
    }

    /**
     * 构建树结构
     * @param pid
     * @param list
     * @return
     */
    private List<DownTreeListVO> getTreeList(Long pid, List<BigScreenTypeEntity> list,List<BigScreenPageEntity> pageList){
        List<DownTreeListVO> children = new ArrayList<>();
        for (BigScreenTypeEntity entity : list){
            DownTreeListVO vo = new DownTreeListVO();
            if (Objects.equals(entity.getPid(), pid)){
                List<DownTreeListVO> treeList = new ArrayList<>();
                treeList.addAll(rootTreeList(entity,pageList));
                treeList.addAll(getTreeList(entity.getId(), list, pageList));
                vo.setChildren(treeList);
                vo.setId(IdWorker.getId());
                vo.setPid(entity.getPid());
                vo.setTypeName(entity.getName());
                vo.setCode(entity.getCode());
                vo.setIsDirct(true);
                children.add(vo);
            }
        }
        return children;
    }

    /**
     * 创建目录
     * @param entity
     * @param pageList
     * @return
     */
    private List<DownTreeListVO> rootTreeList(BigScreenTypeEntity entity,List<BigScreenPageEntity> pageList){
        List<BigScreenPageEntity> collect = pageList.stream().filter(p -> p.getParentCode().equalsIgnoreCase(entity.getCode())).collect(Collectors.toList());
        List<DownTreeListVO> treeList = new ArrayList<>();
        if(collect!=null && collect.size()>0){
            for (BigScreenPageEntity item : collect){
                DownTreeListVO downTreeListVO = new DownTreeListVO();
                downTreeListVO.setBigScreenId(item.getId());
//                downTreeListVO.setBigScreenName(item.getName());
                downTreeListVO.setCode(item.getCode());
                downTreeListVO.setId(IdWorker.getId());
                downTreeListVO.setIsDirct(false);
                downTreeListVO.setPid(entity.getId());
              downTreeListVO.setTypeName(item.getName());
                downTreeListVO.setChildren(new ArrayList<>());
                treeList.add(downTreeListVO);
            }
        }
        return treeList;
    }

    //**********************************菜单栏大屏相关接口**************************************

    /**
     * 根据菜单栏目获取大屏清单
     */
    public List<PublishScreenVO> getScreenListByMenuName(String menuName){
        List<PublishScreenVO> dataList = new ArrayList<>();
        List<BigScreenPageEntity> list = this.list(Wrappers.<BigScreenPageEntity>lambdaQuery()
                .eq(BigScreenPageEntity::getIsPublish, ScreenConstant.PUBLISH)
                //.isNotNull(BigScreenPageEntity::getSeatId)
                .like(BigScreenPageEntity::getPublishDir, menuName)
                .orderByAsc(BigScreenPageEntity::getParentCode,BigScreenPageEntity::getOrderNum));
        //席位列表
        /*List<Long> seatIds = SecurityUtils.getLoginUser().getSeatIds();
        log.info("席位:{}",seatIds.toString());
        if(list!=null && list.size()>0){
            for (BigScreenPageEntity item : list){
                if(SecurityUtils.isAdmin(SecurityUtils.getUserId())){
                    PublishScreenVO publishScreenVO = new PublishScreenVO();
                    publishScreenVO.setCode(item.getCode());
                    publishScreenVO.setName(item.getName());
                    publishScreenVO.setId(item.getId());
                    publishScreenVO.setPcode(item.getParentCode());
                    dataList.add(publishScreenVO);
                }else if(StringUtils.isNotBlank(item.getSeatId())){
                    String bigSeatId = item.getSeatId();
                    List<String> listSeatIds = Arrays.asList(bigSeatId.split(","));
                    Long seatId = seatIds.stream().filter(p -> listSeatIds.contains(String.valueOf(p))).findFirst().orElse(null);
                    if(null != seatId){
                        PublishScreenVO publishScreenVO = new PublishScreenVO();
                        publishScreenVO.setCode(item.getCode());
                        publishScreenVO.setName(item.getName());
                        publishScreenVO.setId(item.getId());
                        publishScreenVO.setPcode(item.getParentCode());
                        dataList.add(publishScreenVO);
                    }
                }
            }
        }*/
        //运行复盘传
        if("replay".equals(menuName)){
            List<BigScreenTypeEntity> typeList = bigScreenTypeService.list(Wrappers.<BigScreenTypeEntity>lambdaQuery()
                    .eq(BigScreenTypeEntity::getType, "bigScreenCatalog")
                    .orderByAsc(BigScreenTypeEntity::getOrderNum)
                    .orderByDesc(BigScreenTypeEntity::getCreateTime));
            Map<String,List<PublishScreenVO>> map = new HashMap<>();
            for (PublishScreenVO item : dataList){
                if(!map.containsKey(item.getPcode())){
                    map.put(item.getPcode(),new ArrayList<>());
                }
                map.get(item.getPcode()).add(item);
            }
            dataList.addAll(getDirectTree(0L,typeList,map));
            dirClear(dataList);
        }
        return dataList;
    }

    private List<PublishScreenVO> getDirectTree(Long pid, List<BigScreenTypeEntity> list,Map<String,List<PublishScreenVO>> map){
        List<PublishScreenVO> children = new ArrayList<>();
        for (BigScreenTypeEntity entity : list){
            PublishScreenVO vo = new PublishScreenVO();
            if (Objects.equals(entity.getPid(), pid)){
                vo.setChilds(getDirectTree(entity.getId(),list,map));
                vo.setId(entity.getId());
                vo.setName(entity.getName());
                vo.setPid(entity.getPid());
                vo.setCode(entity.getCode());
                vo.setBigScreens(map.getOrDefault(entity.getCode(),null));
                children.add(vo);
            }
        }
        return children;
    }

    /**
     * api接口运行复盘传移除没有大屏的目录
     * @param list
     */
    private void dirClear(List<PublishScreenVO> list){
        Iterator<PublishScreenVO> it = list.iterator();
        while (it.hasNext()){
            PublishScreenVO item = it.next();
            if (CollectionUtils.isNotEmpty(item.getChilds())){
                dirClear(item.getChilds());
            }

            if (CollectionUtils.isEmpty(item.getBigScreens())){
                it.remove();
            }
        }
    }

    @Override
    public void auth(ScreenAuthDTO auth){
        BigScreenPageEntity entity = this.getOne(Wrappers.<BigScreenPageEntity>lambdaQuery()
                .eq(BigScreenPageEntity::getCode, auth.getCode()));
        if(null == entity){
            throw new ServiceException("大屏不存在");
        }
        if(CollectionUtils.isEmpty(auth.getPermissions())){
            return;
        }
        StringBuffer auths = new StringBuffer();
        for (Long id : auth.getPermissions()){
            if(auths.length()>0){
                auths.append(",");
            }
            auths.append(id);
        }
        entity.setSeatId(auths.toString());
        updateById(entity);
    }

    @Override
    public List<Long> getAuth(String code){
        BigScreenPageEntity entity = this.getOne(Wrappers.<BigScreenPageEntity>lambdaQuery()
                .eq(BigScreenPageEntity::getCode, code));
        if(null == entity){
            throw new ServiceException("大屏不存在");
        }
        List<Long> list = new ArrayList<>();
        if(StringUtils.isNotBlank(entity.getSeatId())){
            String seatIds = entity.getSeatId();
            String[] seatIdArr = seatIds.split(",");
            for (String id : seatIdArr){
                list.add(Long.parseLong(id));
            }
        }
        return list;
    }
}
